#!/bin/sh -f
# $Id: pybuild.sh b3a8aba613bc 2013/04/26 05:38:41 pgurumur $
# Copyright (c) 2009 Prabhu Gurumurthy  <pgurumur@gmail.com>
# 
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# 
# $Author: pgurumur $
# $Revision: b3a8aba613bc $

# Program name
PROG=`basename $0`

# UID value
UID=`id -u`

# Globals
PYTHON_DIR=
PREFIX=
BUILD_DIR=
CO_VERSION=
MAKE=`which make`
RM="/bin/rm -rf"
MACHINE=`uname`
CC=`which gcc`

build_python () {
   if [ -z ${PYTHON_DIR} ] || [ -z ${BUILD_DIR} ]; then
      echo "${PROG}: Cannot proceed without python and build dir defined!"
      usage
   fi

   if [ -d ${PYTHON_DIR} ]; then
      if [ $? -eq 2 ]; then
         echo "${PROG}: cannot find gmake, bailing..."
         exit 1
      fi

      CONF="${PYTHON_DIR}/configure"
      if [ ! -f ${CONF} ]; then
         echo "${PROG}: cannot find configure file, bailing..."
         exit 1
      fi

      VERSION=`${CONF} -V | awk '$0 ~ /python/ { print $NF; }'`

      if [ -d ${BUILD_DIR} ]; then
         if [ ${PYTHON_DIR} != ${BUILD_DIR} ]; then
            ${RM} ${BUILD_DIR}
         fi
      fi

      mkdir ${BUILD_DIR}
      cd ${BUILD_DIR}
      if [ ${MACHINE} = "OpenBSD" ]; then
         INCLUDES="-I/usr/include "
         THREAD_STACK_SIZE=0x20000
         export CPPFLAGS="-DTHREAD_STACK_SIZE=${THREAD_STACK_SIZE}"
         export CPPFLAGS="${CPPFLAGS} -fPIC ${INCLUDES}"
         export LDFLAGS="-L${BUILD_DIR} -lcurses -lreadline -lutil"
         export LD_LIBRARY_PATH="${BUILD_DIR}:/usr/lib:/usr/local/lib"
      fi

      CONFIGURE_ARGS="--with-fpectl --with-threads --srcdir=${PYTHON_DIR}"
      CONFIGURE_ARGS="${CONFIGURE_ARGS} --enable-ipv6 --enable-shared"
      CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-signal-module"
      if [ ! -z ${PREFIX} ]; then
         CONFIGURE_ARGS="${CONFIGURE_ARGS} --prefix=${PREFIX}"
      fi

      echo -n "building python ${VERSION} with following arguments..."
      echo ${CONFIGURE_ARGS}
      sleep 2
      ${CONF} ${CONFIGURE_ARGS}
      if [ $? -eq 0 ]; then
         ${MAKE} all
         PYLIB=`ls lib*.a | awk '{ 
               split($0, var, ".a"); printf("%s.so\n", var[1]); }'`
         ${MAKE} ${PYLIB}
      fi
   fi
}


clean_build () {

   if [ -z ${PYTHON_DIR} ] || [ -z ${BUILD_DIR} ]; then
      echo "${PROG}: Cannot proceed without python and build dir defined!"
      usage
   fi

   if [ -d ${PYTHON_DIR} -a -d ${BUILD_DIR} ]; then
      CONF="${PYTHON_DIR}/configure"
      VERSION=`${CONF} -V | awk '$0 ~ /python/ { print $NF; }'`
      cd ${BUILD_DIR}
      if [ ! -z $1 ] &&  [ $1 = "all" ]; then
         echo "${PROG}: dist cleaning python ${VERSION}..."
         ${MAKE} distclean
         if [ ${PYTHON_DIR} != ${BUILD_DIR} ]; then
            ${RM} ${BUILD_DIR}
         fi
      else
         echo "${PROG}: cleaning python ${VERSION}..."
         ${MAKE} clean
      fi
   fi
}

check_svn () {
   which svn > /dev/null 2>&1
   if [ $? -ne 0 ]; then
      echo "${PROG}: subversion not installed, cannot proceed..."
      exit 1
   fi
}


svn_update () {

   check_svn
   if [ -z ${PYTHON_DIR} ]; then
      echo "${PROG}: No working copy present, cannot proceed...."
      exit 1
   else
      cd ${PYTHON_DIR}
      svn update .
   fi
}

svn_checkout () {

   check_svn
   if [ -z ${CO_VERSION} ]; then
      CO_VERSION="2.7"
   fi

   PYTHON_URL="http://svn.python.org/projects/python"
   DEST_DIR="python-${CO_VERSION}"
   if [ ${CO_VERSION} = "2.6" ]; then
      svn co ${PYTHON_URL}/branches/release26-maint ${DEST_DIR}
   elif [ ${CO_VERSION} = "3.1" ]; then
      svn co ${PYTHON_URL}/branches/release31-maint ${DEST_DIR}
   elif [ ${CO_VERSION} = "3.2" ]; then
      svn co ${PYTHON_URL}/branches/py3k ${DEST_DIR}
   elif [ ${CO_VERSION} = "2.7" ]; then
      svn co ${PYTHON_URL}/trunk ${DEST_DIR}
   fi
}

usage () {
   echo "${PROG} options [ commands ]"
   echo "options: "
   echo " -s [ python source directory ]"
   echo " -b [ python build directory ]"
   echo " -P [ Prefix where python would be installed ]"
   echo " -V [ Python checkout version ]"
   echo " -h [ prints this help ]"
   echo "commands: "
   echo "   build     [ Build python ]"
   echo "   clean     [ Clean built python ]"
   echo "   update    [ Update python using subversion ]"
   echo "   distclean [ Dist clean built python ]"
   echo "   checkout  [ Checkout python from subversion (default: 2.7) ]"
   exit 1
}

# If we do not have enough arguments, then 
if [ $# -lt 1 ]; then
   usage
else 
   while getopts s:b:P:V:h arg; do
      case ${arg} in
         s)
            PYTHON_DIR=${OPTARG}
            ;;

         b)
            BUILD_DIR=${OPTARG}
            ;;

         P)
            PREFIX=${OPTARG}
            ;;

         V)
            CO_VERSION=${OPTARG}
            ;;

         h)
            usage
            ;;

         *)
            usage
            ;;
      esac
   done

   arg=`echo $* | awk '{ print $NF; }'`

   if [ ! -z ${BUILD_DIR} ]; then
      if [ -d ${BUILD_DIR} ]; then
         uid=
         if [ ${MACHINE} = "OpenBSD" ]; then
            eval $(stat -s ${BUILD_DIR})
            uid=${st_uid}
         elif [ ${MACHINE} = "Linux" ]; then
            uid=`stat -c "%u" ${BUILD_DIR}`
         fi

         if [ ${uid} -ne ${UID} ]; then
            echo "${PROG}: ${BUILD_DIR} is not owned by user with ${UID} uid"
            exit 1
         fi
      else
         echo "${PROG}: ${BUILD_DIR} does not exist"
         exit 1
      fi
   fi

   case ${arg} in
      build)
         build_python
         ;;

      clean)
         clean_build
         ;;

      distclean)
         clean_build "all"
         ;;

      update)
         svn_update
         ;;

      checkout)
         svn_checkout
         ;;

      *)
         usage
         ;;

   esac
fi
